package com.ycwl.aiLive_2d.utils;

import com.ycwl.aiLive_2d.exception.BaseException;

import java.io.*;
import java.nio.channels.FileChannel;

/**
 * @author songmingsong
 * @date 2023/7/10
 */
public class FileSplitUtils {

    /**
     * 文件切片
     *
     * @param file  路径
     * @param count 切片大小
     */
    public static void getSplitFile(String file, int count, String splitFilePath) {

        //预分配文件所占用的磁盘空间，在磁盘创建一个指定大小的文件，“r”表示只读，“rw”支持随机读写
        try {
            RandomAccessFile raf = new RandomAccessFile(new File(file), "r");
            // 写入原始头部信息
            byte[] header = new byte[100]; // 假设头部信息的长度为100字节
            raf.read(header);
            //计算文件大小
            long length = raf.length();
            //计算文件切片后每一份文件的大小
            long maxSize = length / count;
            long offset = 0L;//定义初始文件的偏移量(读取进度)
            //开始切割文件
            for (int i = 0; i < count - 1; i++) { //count-1最后一份文件不处理
                //标记初始化
                long fbegin = offset;
                //分割第几份文件
                long fend = (i + 1) * maxSize;
                //写入文件
                offset = getWrite(file, i, fbegin, fend, header);

            }
            //剩余部分文件写入到最后一份(如果不能平平均分配的时候)
            if (length - offset > 0) {
                //写入文件
                getWrite(file, count - 1, offset, length, header);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException("文件切片异常", 5001);
        }
    }

    /**
     * 文件写入
     *
     * @param file
     * @param index
     * @param begin
     * @param end
     * @param header 文件头
     * @return
     */
    private static long getWrite(String file, int index, long begin, long end, byte[] header) {
        long endPointer = 0L;
        try {
            //申明文件切割后的文件磁盘
            RandomAccessFile in = new RandomAccessFile(new File(file), "r");
            //定义一个可读，可写的文件并且后缀名为.tmp的二进制文件
            String path = "streaming_tts_" + index + ".wav";
            String str = file.replaceAll("streaming_tts_copy.wav", path);
            RandomAccessFile out = new RandomAccessFile(new File(str), "rw");
            out.write(header);
            //申明具体每一文件的字节数组
            byte[] b = new byte[1024];
            int n = 0;
            //从指定位置读取文件字节流
            in.seek(begin);
            //判断文件流读取的边界
            while (in.getFilePointer() <= end && (n = in.read(b)) != -1) {
                //从指定每一份文件的范围，写入不同的文件
                out.write(b, 0, n);
            }
            //定义当前读取文件的指针
            endPointer = in.getFilePointer();
            //关闭输入流
            in.close();
            //关闭输出流
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException("文件切片后写入异常", 5001);
        }
        return endPointer;
    }

    /**
     * 文件拷贝
     *
     * @param sourceUrl 资源
     * @param destUrl   目标
     * @throws IOException
     */
    public static void copyFiles(String sourceUrl, String destUrl) throws IOException {
        FileChannel inputChannel = null;
        FileChannel outputChannel = null;
        try {
            inputChannel = new FileInputStream(sourceUrl).getChannel();
            outputChannel = new FileOutputStream(destUrl).getChannel();
            outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
        } finally {
            inputChannel.close();
            outputChannel.close();
        }
    }
}
